package com.cby.code.util;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.TrafficStats;
import android.os.Debug;
import android.util.Log;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigDecimal;

/**
 * @description: SystemUtils
 * @author: ChenBaoYang
 * @createDate: 2022/4/2 10:17 上午
 */
public class SystemUtils {

    /**
     * 系统空闲内存
     * @param context
     * @return
     */
    public static long getSysFreeMemory(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(mi);
        return mi.availMem;
    }

    /**
     * 进程内存上限
     * @return
     */
    public static int getMemoryMax() {
        return (int) (Runtime.getRuntime().maxMemory()/1024);
    }

    /**
     * 进程总内存
     * @param pid
     * @param context
     * @return
     */
    public static int getPidMemorySize(int pid, Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int[] myMempid = new int[] { pid };
        Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(myMempid);
        int memSize = memoryInfo[0].getTotalPss();
        //        dalvikPrivateDirty： The private dirty pages used by dalvik。
        //        dalvikPss ：The proportional set size for dalvik.
        //        dalvikSharedDirty ：The shared dirty pages used by dalvik.
        //        nativePrivateDirty ：The private dirty pages used by the native heap.
        //        nativePss ：The proportional set size for the native heap.
        //        nativeSharedDirty ：The shared dirty pages used by the native heap.
        //        otherPrivateDirty ：The private dirty pages used by everything else.
        //        otherPss ：The proportional set size for everything else.
        //        otherSharedDirty ：The shared dirty pages used by everything else.
        return memSize;
    }

    /**
     * 获取cpu的占用率
     *
     * @param pid
     * @return
     */
    public static double getProcessCpuUsage(String pid) {
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();
            String[] toks = load.split(" ");

            double totalCpuTime1 = 0.0;
            int len = toks.length;
            for (int i = 2; i < len; i ++) {
                totalCpuTime1 += Double.parseDouble(toks[i]);
            }

            RandomAccessFile reader2 = new RandomAccessFile("/proc/"+ pid +"/stat", "r");
            String load2 = reader2.readLine();
            String[] toks2 = load2.split(" ");

            double processCpuTime1 = 0.0;
            double utime = Double.parseDouble(toks2[13]);
            double stime = Double.parseDouble(toks2[14]);
            double cutime = Double.parseDouble(toks2[15]);
            double cstime = Double.parseDouble(toks2[16]);

            processCpuTime1 = utime + stime + cutime + cstime;

            try {
                Thread.sleep(360);
            } catch (Exception e) {
                e.printStackTrace();
            }
            reader.seek(0);
            load = reader.readLine();
            reader.close();
            toks = load.split(" ");
            double totalCpuTime2 = 0.0;
            len = toks.length;
            for (int i = 2; i < len; i ++) {
                totalCpuTime2 += Double.parseDouble(toks[i]);
            }
            reader2.seek(0);
            load2 = reader2.readLine();
            String []toks3 = load2.split(" ");

            double processCpuTime2 = 0.0;
            utime = Double.parseDouble(toks3[13]);
            stime = Double.parseDouble(toks3[14]);
            cutime = Double.parseDouble(toks3[15]);
            cstime = Double.parseDouble(toks3[16]);

            processCpuTime2 = utime + stime + cutime + cstime;
            double usage = (processCpuTime2 - processCpuTime1) * 100.00
                    / ( totalCpuTime2 - totalCpuTime1);
            BigDecimal b = new BigDecimal(usage);
            double res = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            return res;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return 0.0;
    }

    //
    //
    //，方法如下：

    /**
     * 1.uid获取可根据包名得到
     * 2.这里mUid是应用的uid，非进程id pid，注意区分
     * 3.通过uid获取流量数据，上行和下行
     * @param pkgname
     * @return
     */
    public static int getUidByPkgName(Context context, String pkgname)  {
        PackageManager pm = context.getPackageManager();
        try {
            ApplicationInfo ai = pm.getApplicationInfo(pkgname, 0);
            Log.i("chenby", String.valueOf(ai.uid));
            return ai.uid;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 进程流量统计
     * @param mUid
     * @return
     */
    public  static TrafficInfo collect(int mUid) {
        long upload  = TrafficStats.getUidRxBytes(mUid);
        long download = TrafficStats.getUidTxBytes(mUid);
        return new TrafficInfo(upload, download);
    }

    public static class TrafficInfo{

        private long upload;
        private long download;

        public TrafficInfo(long upload, long download) {
            this.upload = upload;
            this.download = download;
        }

        public long getUpload() {
            return upload;
        }

        public long getDownload() {
            return download;
        }
    }
}
